﻿using FaceWebServer.DB.Device;
using FaceWebServer.Interface;
using FaceWebServer.Utility;
using FaceWebServer.Utility.JWT;
using FaceWebServer.Utility.Model;
using FaceWebServer.Utility.ExpressionExtend;
using FC8280TServer.Controllers.User;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using FaceWebServer.Utility.FilterAttribute;
using Newtonsoft.Json;
using FaceWebServer.DB.System;

namespace FC8280TServer.Controllers.FaceDevice
{
    [Route("api/[controller]")]
    [ApiController]
    public class FaceDeviceController : ControllerBase
    {

        private readonly ILogger<FaceDeviceController> _logger;
        private IMyMemoryCache _Cache;
        private IFaceDriveService _DeviceDB;

        public FaceDeviceController(ILogger<FaceDeviceController> logger,
            IFaceDriveService door, IMyMemoryCache mycache)
        {
            _logger = logger;
            _DeviceDB = door;
            _Cache = mycache;
        }


        /// <summary>
        /// 获取已安装的设备表格
        /// </summary>
        /// <param name="par"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("GetDeviceTable")]
        [Authorize]
        [TypeFilter(typeof(VerifyActionFilterAttribute))]
        public IActionResult GetDeviceTable([FromForm] DeviceQueryParameter par)
        {

            List<Expression<Func<FaceDeviceDetail, bool>>> oWheres = new();
            if (!string.IsNullOrWhiteSpace(par.DeviceID)) oWheres.Add(x => x.DeviceID.Contains(par.DeviceID));
            if (!string.IsNullOrWhiteSpace(par.DeviceName)) oWheres.Add(x => x.DeviceName.Contains(par.DeviceName));

            _logger.LogInformation("获取设备列表");
            var devices = _DeviceDB.QueryPage(
                x => new
                {
                    x.ID,
                    x.DeviceID,
                    x.DeviceName,
                    x.LastKeepaliveTime,
                    x.OnlineTime,
                    x.ParameterAccessType,
                    x.ParameterKeepOpenDoor,
                    x.ParameterLaissezSwitch,
                    x.ParameterProductionDate,
                    x.ParameterFirmwareMsg
                },
                oWheres, par.pageSize, par.pageIndex,
                x => x.DeviceID,
                par.isAsc);

            return new JsonResult(new JsonResultModel(devices));
        }


        /// <summary>
        /// 更新设备信息
        /// </summary>
        /// <param name="par"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("Update")]
        [Authorize]
        [TypeFilter(typeof(VerifyActionFilterAttribute))]
        public IActionResult Update([FromForm] DeviceUpdateParameter par)
        {
            var device = _DeviceDB.Find<FaceDeviceDetail>(par.ID);
            if (device == null) return new JsonResult(new JsonResultModel(200, "设备不存在"));

            #region 重复过滤
            List<Expression<Func<FaceDeviceDetail, bool>>> oWheres = new();
            oWheres.Add(x => x.ID != par.ID);
            Expression<Func<FaceDeviceDetail, bool>> w1 = x => x.DeviceID.Equals(par.DeviceID);
            Expression<Func<FaceDeviceDetail, bool>> w2 = x => x.DeviceName.Equals(par.DeviceName);
            oWheres.Add(w1.Or(w2));

            var devices = _DeviceDB.QueryPage(
                x => new
                {
                    x.ID,
                    x.DeviceID,
                    x.DeviceName
                },
                oWheres, 100, 1,
                x => x.DeviceID,
                true, true);
            if (devices.TotalCount > 0)
            {
                foreach (var p in devices.DataList)
                {
                    if (p.DeviceID == par.DeviceID)
                    {
                        return new JsonResult(new JsonResultModel(201, $"设备SN重复"));
                    }
                    if (p.DeviceName == par.DeviceName)
                    {
                        return new JsonResult(new JsonResultModel(202, $"设备名称重复"));
                    }
                }

            }
            #endregion

            _logger.LogInformation($"更新设备：ID:{device.ID} SN:{device.DeviceID} Name:{device.DeviceName}");
            par.CopyTo(device);
            _logger.LogInformation(device.ParameterLightSwitch.ToString());
            _logger.LogInformation(device.ParameterLaissezSwitch.ToString());
            device.LastUpdatetime = DateTime.Now;


            _DeviceDB.AddUserLog("设备管理",
                $"修改设备参数：{device.DeviceName}({device.DeviceID})，参数信息：{JsonConvert.SerializeObject(device)}",
                $"{device.DeviceName}({device.DeviceID})", string.Empty);

            _DeviceDB.Update(device);

            return new JsonResult(new JsonResultModel(new { par.ID }));
        }

        /// <summary>
        /// 删除设备
        /// </summary>
        /// <param name="par"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("Delete")]
        [Authorize]
        [TypeFilter(typeof(VerifyActionFilterAttribute))]
        public IActionResult Delete([FromForm] DeviceDeleteParameter par)
        {

            if (par.DeviceIDs == null)
            {
                return new JsonResult(new JsonResultModel(1, "未选择需要删除的设备"));
            }
            if (par.DeviceIDs.Count == 0)
            {
                return new JsonResult(new JsonResultModel(1, "未选择需要删除的设备"));
            }

            //查询需要删除的设备
            HashSet<int> devIDLists = new HashSet<int>(par.DeviceIDs);
            var devices = _DeviceDB.Query<FaceDeviceDetail>(x => devIDLists.Contains(x.ID)).Select(x => new FaceDeviceDetail
            {
                ID = x.ID,
                DeviceName = x.DeviceName,
                DeviceID = x.DeviceID
            });
            foreach (var d in devices)
            {
                _DeviceDB.AddUserLog("设备管理", $"删除设备：{d.DeviceName}({d.DeviceID})",
                $"{d.DeviceName}({d.DeviceID})", string.Empty);
            }
            _logger.LogInformation($"删除设备操作：ID:{string.Join(",", par.DeviceIDs.Select(x => x.ToString()))}");


            _DeviceDB.Delete(devices.AsEnumerable());
            return new JsonResult(new JsonResultModel(par));
        }


        /// <summary>
        /// 获取设备详情
        /// </summary>
        /// <param name="par"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetDeviceDetail")]
        [Authorize]
        public IActionResult GetDeviceDetail([FromQuery] int ID)
        {
            var device = _DeviceDB.Find<FaceDeviceDetail>(ID);
            if (device == null) return new JsonResult(new JsonResultModel(10, "设备不存在"));

            return new JsonResult(new JsonResultModel(device));
        }


        /// <summary>
        /// 获取设备出厂默认值
        /// </summary>
        /// <param name="par"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("GetDefaultValue")]
        [Authorize]
        public IActionResult GetDefaultValue()
        {
            var device = _DeviceDB.GetDefaultValue();
            var sJson = JsonConvert.SerializeObject(device);

            DeviceBaseParameter par = JsonConvert.DeserializeObject<DeviceBaseParameter>(sJson);
            return new JsonResult(new JsonResultModel(par));
        }


        /// <summary>
        /// 设置设备出厂默认值
        /// </summary>
        /// <param name="par"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("SetDefaultValue")]
        [Authorize]
        [TypeFilter(typeof(VerifyActionFilterAttribute))]
        public IActionResult SetDefaultValue([FromForm] DeviceBaseParameter par)
        {
            var sysdb = _DeviceDB.GetSystemKVDBSet();
            var kv = sysdb.Find("DefaultDevice");
            var sJson = JsonConvert.SerializeObject(par);


            _DeviceDB.AddUserLog("设备管理", $"更新设备出厂默认值：{sJson}");


            if (kv == null)
            {
                kv = new() { Key = "DefaultDevice", Value = sJson };
                _DeviceDB.Insert<SystemKV>(kv);
            }
            else
            {
                kv.LastUpdateTime = DateTime.Now;
                kv.Value = sJson;
                _DeviceDB.Update(kv);

            }



            return new JsonResult(new JsonResultModel());
        }

    }
}
